/*
* 模型
* */
define(['classer', 'eventer', 'objecter'], function(classer, eventer, objecter){
	var Model = classer.extend({
		// 属性
		props : {},

		/**
		 * @desc 初始化
		 * */
		init : function () {
			// 默认属性
			this._props = objecter.extend(true, {}, this.props);
			// 事件初始化
			this._eventer = new eventer(this);
		},

		/**
		 * @desc 设置属性
		 * @param <String/Object> key 改变的键名或需要改变的数据对象
		 * @param <Any> value 任意值
		 * */
		set : function (key, value) {
			var me = this, props = this.props,
				mockAttr = objecter.clone(props), options = {};
			if(objecter.isString(key)){
				options[key] = value;
			}else if(objecter.isPlainObject(key)){
				options = key;
			}
			// 不符合条件
			else{
				return false;
			}

			var bChange = false;
			each(options, props);

			if(bChange){
				this._emit('change', [], options, mockAttr);
			}

			// 遍历设置对象
			function each(_new, _old){
				for(var item in _new){
					var m = _new[item],
						n = _old[item];
					if(objecter.isPlainObject(m) && objecter.isPlainObject(n)){
						each(m , n);
					}else if(m !== n){
						var mockN = objecter.clone(n);
						bChange = true;
						_old[item] = m;
						me._emit('change', [item], m, mockN);
					}
				}
			}
		},

		/**
		 * @desc 获取属性值
		 * @param <String> key 改变的键名或需要改变的数据对象
		 * @return <Any> 属性值
		 * */
		get : function (key) {
			var value = undefined;
			if(objecter.isString(key)){
				value = this._attr[key];
			}else if(typeof key === 'undefined'){
				value = this._attr;
			}
			return value;
		},

		// /* @desc 事件绑定
		//  * @param <String> name 事件名
		//  * @param <Function> fn 绑定方法
		//  * */
		// on : function(name, fn){
		// 	_eventer.on(name, fn);
		// },
		//
		// /* @desc 关闭事件
		//  * @param <String> name 事件名
		//  * @param <Function> fn 绑定方法
		//  * */
		// off : function(name, fn){
		// 	_eventer.off(name, fn);
		// },
		//
		// /* @desc 触发事件
		//  * @param <String> name 事件名
		//  * */
		// trigger : function(name){
		// 	this._eventer.trigger(name);
		// },

		/**
		 * @desc 事件检测
		 * @param <String> type 事件类型
		 * @param <Array> path 路径数组
		 * */
		_emit : function (type, path, _new, _old) {
			var name = type;
			name += path.length < 1 ? '' : ':' + path.join('.');
			this.trigger(name, _new, _old);
		}
	});

	return Model;
});